/*********************************************************************************
Organization 					: 				Georgia Institute of Technology
  
Institute 						:				Cognitive Computing Group(CCL)
 
Authors							: 				Manish Mehta 
 												
Class							:				Reasoner
 
Function						: 				Main class for carrying out behavior adaptation
****************************************************************************/
package behavioradaptation.reasoner;


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.List;

import cbr.episodicCBR.EpisodicCBR;

import trace.Testtrace;
import trace.Trace;
import behavioradaptation.analysisdata.AbstractedTrace;
import behavioradaptation.analysisdata.FixData;
import behavioradaptation.analysisdata.PlanFailuresData;
import behavioradaptation.failurepattern.NoPeasCompositeFP;
import behavioradaptation.failurepattern.NoPeasPeasKilledFP;
import behavioradaptation.failurepattern.NoResCompositeFP;
import behavioradaptation.failurepattern.NoResPeasKilledFP;
import behavioradaptation.failurepattern.PeasKilledAvAttUnitsFP;
import behavioradaptation.fixes.BOFixes;
import behavioradaptation.fixes.BuildingIdleFix;
import behavioradaptation.fixes.NoPeasCompositeFix;
import behavioradaptation.fixes.PeasantIdleFix;

public class Reasoner {

	public static enum m_conditionType {PRECONDITION, ALIVECONDITION, POSTCONDITION};
	public static enum m_patternType {NORESOURCES, NORESOURCES_PEASANTKILLED,
									PEASANT_KILLED, PEASANT_KILLED_AVATTACKUNITS, 
									PEASANT_KILLED_NO_PEASANT, PEASANT_KILLED_AVATTACKUNITS_NO_PEASANT, NO_PEASANT};
	Trace m_trace;
	PatternTracker m_patternTracker;
	List<PlanFailuresData> m_planFailuresList;
	AbstractedTrace m_abstractedTrace;
	PlanFailureTracker m_planfailureTracker;
	NoPeasCompositeFP m_comNoPeas ;	
	NoPeasPeasKilledFP m_noPeasPeasKilled ;
	NoResCompositeFP m_comNoRes ;	
	NoResPeasKilledFP m_noResPeasKilled;
	PeasKilledAvAttUnitsFP m_pkaau;
	public EpisodicCBR m_cbr;
	public static PrintStream logger; // declare a print stream object
	FileOutputStream modlog; // declare a file output object
	PrintStream plog; // declare a print stream object
	  
	public Reasoner(Trace a_trace, EpisodicCBR a_cbr) throws FileNotFoundException
	{
		m_cbr = a_cbr;
		m_trace = a_trace;
		m_comNoPeas = new NoPeasCompositeFP();	
		m_noPeasPeasKilled = new NoPeasPeasKilledFP();
		m_comNoRes = new NoResCompositeFP();	
		m_noResPeasKilled = new NoResPeasKilledFP();
		m_pkaau = new PeasKilledAvAttUnitsFP();
		
        modlog = new FileOutputStream("modlog_behavioradaptation.txt");
        // Connect print stream to the output stream
        plog = new PrintStream( modlog );      
        logger = plog;
		
	}
	public void setTrace( Trace a_trace)
	{
		m_trace = a_trace;
	}
	
	public void reason(Trace a_trace) throws Exception
	{
		initialize(a_trace);
		Reasoner.logger.println("*************************Modifications Started*************************");
		detectFailuresandFix();
		Reasoner.logger.println("*************************Modifications finished*************************");
		
	}
	
	public void initialize(Trace a_trace) throws Exception
	{
		m_abstractedTrace = new AbstractedTrace(a_trace);
		m_patternTracker = new PatternTracker(a_trace);
		m_planfailureTracker = new PlanFailureTracker(a_trace);
		m_planFailuresList = m_planfailureTracker.findPlanFailures();
		// Get the abstracted Trace from the Execution Trace
		m_patternTracker.abstractDataFromTrace(m_abstractedTrace);
	
	}
	/*
	 * Detect the different failures and fix them 
	
	 */ 
	public void detectFailuresandFix() throws Exception
	{
		FixData a_fxdata = new FixData();
		boolean pat_detected = false;
		pat_detected = m_comNoPeas.detectPattern(m_planFailuresList, m_abstractedTrace, a_fxdata);
		boolean fix_found = false;
		if(pat_detected && !fix_found)
		{
			NoPeasCompositeFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
			fix_found = true;
		}
		
		System.out.println("Pattern Detected: Complex No Peasant" + pat_detected);
		pat_detected = m_noPeasPeasKilled.detectPattern(m_planFailuresList, m_abstractedTrace, a_fxdata);
		if(pat_detected && !fix_found)
		{
			NoPeasCompositeFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
			fix_found = true;
		}
		System.out.println("Pattern Detected: No Peasant Peasant Killed" + pat_detected);		
		if(pat_detected && !fix_found)
		{
			pat_detected = m_comNoRes.detectPattern(m_planFailuresList, m_abstractedTrace, a_fxdata);
			fix_found = true;
		}
		System.out.println("Pattern Detected: Complex No Resources" + pat_detected);
	
		pat_detected = m_noResPeasKilled.detectPattern(m_planFailuresList, m_abstractedTrace, a_fxdata);
		if(pat_detected && !fix_found)
		{	
			NoPeasCompositeFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
			fix_found = true;
		}
		if(!fix_found)
			NoPeasCompositeFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
		
		System.out.println("Pattern Detected: No Resources Peasant Killed" + pat_detected);		
		PeasantIdleFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
		BuildingIdleFix.fix(m_planFailuresList, m_abstractedTrace, a_fxdata, m_cbr);
		BOFixes.findFixedBOPlans(m_planFailuresList, m_abstractedTrace, m_cbr);	
	}
	public static void main(String[] args) {
		Testtrace t = new Testtrace();
		t.readSerialize("traces/game-trace.dat");
		EpisodicCBR a_cbr = new EpisodicCBR();
		try {
			Reasoner r = new Reasoner(t.tr, a_cbr);
			r.reason(t.tr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("I m done");
	}

}
